
PLUG.Platform = PLUG_PLATFORM_CLIENT

PLUG.ClassName = "cl_menu"
PLUG.PrintName = "Clientside Menu"
PLUG.Author = "thomasfn"

PLUG.Hard = true

function PLUG:Initialize()
	plugs.Call( "AddMainMenuItem", "playermenu", "Player Management", "gmanage/ico_user", "manage_players" )
	plugs.Call( "AddMainMenuItem", "groupmenu", "Group Management", "gmanage/ico_group", "manage_groups" )
	plugs.Call( "AddMainMenuItem", "servermenu", "Server Management", "gmanage/ico_servermanage", "manage_server" )
	plugs.Call( "AddMainMenuItem", "limitsmenu", "Player Limits", "gmanage/ico_limits", "manage_limits" )

	self:CreateDerma()
end

function PLUG:CreateDerma()
	local pl = self
	local PANEL
	
	
	PANEL = {}
	local white = Color( 255, 255, 255 )
	local whitea = Color( 255, 255, 255 )
	function PANEL:Setup()
		self.StartTime = CurTime()
		self.EndTime = CurTime() + 1
		self:SetPos( 0, 0 )
		self:SetSize( ScrW(), ScrH() )
		local ticker = vgui.Create( "DLabel", self )
		ticker:SetPos( self:GetWide()*0.5, self:GetTall()*0.32 )
		ticker:SetText( "" )
		self.Ticker = ticker
		self.Closing = false
		// plugs.Call( "DisableMenuOpen", true )
	end
	function PANEL:FadeOut()
		local t = self:GetTrans()
		if (t < 1) then
			// We are still fading in!!!
			// Wait until we finish before we fade out..
			self.FadeOutOnFinish = true
		else
			self.Closing = true
			self.StartTime = CurTime()
			self.EndTime = CurTime() + 0.6
			if (self.ButtonRow) then self.ButtonRow:FadeOut() end
		end
	end
	function PANEL:TickerMessage( msg )
		local ticker = self.Ticker
		ticker:SetText( msg )
		ticker:SizeToContents()
		ticker:SetPos( (self:GetWide()*0.5)-(ticker:GetWide()*0.5), self:GetTall()*0.32 )
		self.TickerStart = CurTime()
		self.TickerEnd = CurTime()+5
	end
	function PANEL:GetTrans()
		return math.Clamp( (CurTime() - self.StartTime) / (self.EndTime - self.StartTime), 0, 1 )
	end
	local bgcol = Color( 0, 0, 0 )
	local txtcol = Color( 255, 255, 255 )
	function PANEL:Paint()
		local t = self:GetTrans()
		if (self.Closing) then
			bgcol.a = (1-t) * 128
			whitea.a = (1-t) * 255
		else
			bgcol.a = t * 128
			whitea.a = t * 255
		end
		surface.SetDrawColor( bgcol )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		draw.SimpleText( "GManage - Menu", "ScoreboardHead", self:GetWide()*0.5, self:GetTall()*0.02, whitea, 1, TEXT_ALIGN_TOP )
		if (self.Ticker && self.TickerStart && self.TickerEnd) then
			local td = math.Clamp( (CurTime() - self.TickerStart) / (self.TickerEnd - self.TickerStart), 0, 1 )
			if (td <= 0.25) then
				txtcol.a = (td/0.25)*255
			end
			if ((td > 0.25) && (td <= 0.75)) then
				txtcol.a = 255
			end
			if (td > 0.75) then
				txtcol.a = 255-((td-0.75)/0.25*255)
			end
			self.Ticker:SetTextColor( txtcol )
		end
	end
	function PANEL:Think()
		local t = self:GetTrans()
		if (self.Closing) then
			if (t >= 1) then
				// plugs.Call( "DisableMenuOpen", false )
				self:Remove()
			end
		else
			if ((t > 0.1) && (!self.ButtonRow)) then
				local brow = vgui.Create( "GMAN_ButtonRow", self )
				brow:SetPos( 0, self:GetTall() * 0.15 )
				brow:SetSize( self:GetWide(), self:GetTall() * 0.25 )
				brow:Setup()
				self.ButtonRow = brow
			end
			if ((t > 0.6) && (!self.CloseButton)) then
				local btn = vgui.Create( "DButton", self )
				btn:SetText( "X" )
				btn:SetSize( 32, 32 )
				btn:SetPos( ScrW() - btn:GetWide() - 10, 10 )
				function btn:DoClick()
					plugs.Call( "CloseMenu" )
				end
				function btn:DoRightClick()
					RunConsoleCommand( "jpeg" )
				end
				function btn:Think()
					if (pl.CountDown && pl.CountDown:IsValid()) then
						btn:SetPos( 0, 0 )
					else
						btn:SetPos( ScrW() - btn:GetWide() - 10, 10 )
					end
				end
				self.CloseButton = btn
			end
			if ((t >= 1) && (self.FadeOutOnFinish)) then
				self.FadeOutOnFinish = false
				self:FadeOut()
			end
		end
	end
	vgui.Register( "GMAN_MMenu", PANEL, "PANEL" )
	
	
	PANEL = {}
	function PANEL:Setup()
		self.StartTime = CurTime()
		self.EndTime = CurTime() + 0.75
		local btns = plugs.Call( "GetMainMenuItems_PRIV" )
		self.Buttons = {}
		local cnt = 0
		local btncnt = #btns
		local perbtn = self:GetWide() / btncnt
		for _, v in pairs( btns ) do
			if (plugs.Call( "HasPriv", v.Priv )) then
				cnt = cnt + 1
				local btn = vgui.Create( "GMAN_ImgButton", self )
				btn:SetText( "" )
				btn:SetSize( 64, 64 )
				btn:SetPos( (self:GetWide() * 0.5)-32, 0 )
				btn._CLASSNAME = v.ClassName
				btn._CALCX = ((cnt-0.5) * perbtn)-32
				btn._IMAGE = v.Image
				btn._PRINTNAME = v.PrintName
				function btn:DoClick()
					plugs.Call( "OpenSubMenu", self._CLASSNAME )
				end
				table.insert( self.Buttons, btn )
				
				local idtxt = vgui.Create( "GMAN_BtnHoverText", self )
				idtxt:Setup( v.PrintName )
				idtxt:SetPos( 0, self:GetTall()*0.5 )
				idtxt:SetSize( self:GetWide(), self:GetTall()*0.5 )
				
				btn._IDTXT = idtxt
			end
		end
		self._HOVERBUTTON = ""
	end
	function PANEL:GetTrans()
		local t = math.Clamp( (CurTime() - self.StartTime) / (self.EndTime - self.StartTime), 0, 1 )
		if (self.FadingOut) then t = 1 - t end
		return t
	end
	local darkcol = Color( 50, 50, 50, 128 )
	function PANEL:Think()
		local t = self:GetTrans()
		for _, v in pairs( self.Buttons ) do
			local x, y = v:GetPos()
			v:SetPos( math.Mid( (self:GetWide() * 0.5)-32, v._CALCX, t ), y )
		end
	end
	function PANEL:FadeOut()
		self.FadingOut = true
		self.StartTime = CurTime()
		self.EndTime = CurTime() + 0.75
	end
	function PANEL:Paint()
		// draw.SimpleText( self._HOVERBUTTON or "", "ScoreboardSub", self:GetWide()*0.5, self:GetTall()*0.5, white, 1, TEXT_ALIGN_TOP )
	end
	function PANEL:EnableHoverButton( b, text )
		
	end
	vgui.Register( "GMAN_ButtonRow", PANEL, "PANEL" )
	
	
	
	local PANEL = {}
	self.Text = ""
	function PANEL:Setup( txt )
		self.Text = txt or "ERROR"
		self.Col = Color( 255, 255, 255 )
	end
	function PANEL:FadeIn()
		self.StartTime = CurTime()
		self.EndTime = CurTime() + 0.4
		self.StartAlpha = 0
		self.EndAlpha = 255
	end
	function PANEL:FadeOut()
		self.StartTime = CurTime()
		self.EndTime = CurTime() + 0.4
		self.StartAlpha = 255
		self.EndAlpha = 0
	end
	function PANEL:Check()
		self.StartTime = self.StartTime or 0
		self.EndTime = self.EndTime or 0
		self.StartAlpha = self.StartAlpha or 0
		self.EndAlpha = self.EndAlpha or 0
	end
	function PANEL:Think()
		self:Check()
		local dec = 1 - math.Clamp( (self.EndTime - CurTime()) / 0.3, 0, 1 )
		self.Dec = dec
	end
	function PANEL:Paint()
		self:Check()
		local dec = self.Dec
		self.Col.a = math.Mid( self.StartAlpha, self.EndAlpha, dec )
		draw.SimpleText( self.Text, "ScoreboardSub", self:GetWide()*0.5, self:GetTall()*0.5, self.Col, 1, 1 )
	end
	vgui.Register( "GMAN_BtnHoverText", PANEL, "PANEL" )
	
	
	PANEL = {}
	function PANEL:OnCursorEntered()
		self._HOVER = true
		/*local p = self:GetParent()
		if (p) then p._HOVERBUTTON = self._PRINTNAME end*/
		if (self._IDTXT) then self._IDTXT:FadeIn() end
	end
	function PANEL:OnCursorExited()
		self._HOVER = false
		/*local p = self:GetParent()
		if (p) then p._HOVERBUTTON = "" end*/
		if (self._IDTXT) then self._IDTXT:FadeOut() end
	end
	function PANEL:Paint()
		if (!self._IMAGE) then return end
		surface.SetTexture( self._IMAGE )
		local a = 200
		if (self._HOVER) then
			a = 255
		end
		surface.SetDrawColor( 255, 255, 255, a )
		surface.DrawTexturedRect( 0, 0, self:GetWide(), self:GetTall() )
	end
	vgui.Register( "GMAN_ImgButton", PANEL, "DButton" )
	
	
	PANEL = {}
	local btncol_a = Color( 60, 60, 60 )
	local btncol_b = Color( 100, 100, 100 )
	local btncol_c = Color( 100, 100, 200 )
	local white = Color( 255, 255, 255 )
	function PANEL:SetNumericID( id )
		self._ID = id
		if (math.Round( id ) != id) then
			self._COL = btncol_a
		else
			self._COL = btncol_b
		end
	end
	function PANEL:Paint()
		self._COL = self._COL or btncol_a
		local col = self._COL
		if (self._SELECTED) then col = btncol_c end
		surface.SetDrawColor( col )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		self._LBL = self._LBL or "Button"
		self._FNT = self._FNT or "default"
		draw.SimpleText( self._LBL, self._FNT, self:GetWide()*0.5, self:GetTall()*0.5, white, 1, 1 )
	end
	function PANEL:DoClick()
		local p = self:GetParent()
		if (p) then
			if (p._ITEMS) then
				for _, v in pairs( p._ITEMS ) do
					if (v) then v._SELECTED = false end
				end
			end
			self._SELECTED = true
			p:DoCommand( self._ID )
		end
	end
	function PANEL:SetTxt( txt )
		self:SetText( "" )
		self._LBL = txt
	end
	vgui.Register( "GMAN_CatButton", PANEL, "DButton" )

	
	PANEL = {}
	local countdownbg = Color( 50, 50, 50, 200 )
	function PANEL:Paint()
		surface.SetDrawColor( countdownbg )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		local cnt
		for cnt=1, #self._TXT do
			local t = self._TXT[ cnt ]
			if (string.Left( t, 1 ) == "@") then
				local r = string.Right( t, string.len( t ) - 1 )
				local tl = math.ceil( (self.CreateTime+tonumber( r )) - CurTime() )
				t = string.ToMinutesSeconds( tl )
				if (tl < 0) then
					self:OnRemove()
					self:Remove()
				end
			end
			draw.SimpleText( t, "default", self:GetWide()*0.5, (cnt-1)*18 + 4, white, 1, TEXT_ALIGN_TOP )
		end
	end
	function PANEL:SetText( txt )
		if (type( txt ) == "table") then
			self._TXT = txt
		else
			self._TXT = { txt }
		end
		self:SetHeight( #self._TXT*18 + 8 )
		self.CreateTime = CurTime()
	end
	vgui.Register( "GMAN_CountDown", PANEL, "PANEL" )
end

function PLUG:CreateLabel( text, x, y, par )
	local lbl = vgui.Create( "DLabel", par )
	lbl:SetText( text )
	lbl:SizeToContents()
	lbl:SetPos( x - (lbl:GetWide()*0.5), y )
	return lbl
end

function PLUG:CreateLabel2( text, x, y, par )
	local lbl = vgui.Create( "DLabel", par )
	lbl:SetText( text )
	lbl:SizeToContents()
	lbl:SetPos( x, y )
	return lbl
end

function PLUG:CreateTextbox( x, y, w, par )
	local txt = vgui.Create( "DTextEntry", par )
	txt:SetPos( x, y )
	txt:SetSize( w, 20 )
	return txt
end

function PLUG:CreateApplyEntry( text, val, x, y, txtw, btnw, h, par, onclick )
	local lbl = self:CreateLabel2( text .. ": ", x, y, par )
	local txt = vgui.Create( "DTextEntry", par )
	txt:SetPos( x + lbl:GetWide() + 5, y )
	txt:SetSize( txtw, h )
	txt:SetValue( val )
	local btn = vgui.Create( "DButton", par )
	btn._TXT = txt
	btn:SetPos( x + lbl:GetWide() + 10 + txtw, y )
	btn:SetSize( btnw, h )
	btn:SetText( "Apply" )
	function btn:GetTXT()
		return self._TXT:GetValue()
	end
	btn.DoClick = onclick
	return btn
end

function PLUG:AddPlayerOpList( window, title, id, x, w )
	self:CreateLabel( title, x + 10 + (w*0.5), 10, window )
	local pn = vgui.Create( "DComboBox", window )
	pn:SetPos( 10 + x, 30 )
	pn:SetSize( w, window:GetTall()-40 )
	pn:SetMultiple( false )
	local options = plugs.MergeCall( "BuildPlayerActionList", id )
	local cnt = 0
	for _, v in pairs( options ) do
		if (plugs.Call( "HasPriv", v[3] )) then
			cnt = cnt + 1
			local item = pn:AddItem( v[2] )
			item._OPID = v[1]
		end
	end
	if (cnt == 0) then
		pn:AddItem( "No Actions" )
	else
		pn.SelectItem2 = pn.SelectItem
		function pn:SelectItem( item, onlyme )
			local op = item._OPID
			if (op) then
				plugs.Call( "RunPlayerOperation", op, self:GetParent()._PLAYER )
			end
			self:SelectItem2( item, onlyme )
		end
	end
end

function PLUG:CreateLimitSlider( min, max, text )
	local sl = vgui.Create( "DNumSlider" )
	sl:SetHeight( 40 )
	sl:SetText( text )
	sl:SetMin( min )
	sl:SetMax( max )
	sl:SetDecimals( 0 )
	sl._CHANGED = false
	function sl:OnValueChanged()
		self._CHANGED = true
	end
	return sl
end

function PLUG:CreateOptionButton( parent, x, y, w, h, text, options, callback )
	local btn = vgui.Create( "DButton", parent )
	btn:SetPos( x, y )
	btn:SetSize( w, h )
	btn:SetText( text )
	function btn:DoClick()
		local men = DermaMenu()
		for _, v in pairs( options ) do
			local opname = v[1]
			men:AddOption( v[2], function() callback( opname ) end )
		end
		men:Open()
	end
end

function PLUG:CreateCountdown( text )
	self:DestroyCountdown()
	local cd = vgui.Create( "GMAN_CountDown" )
	cd:SetText( text )
	cd:SetWide( ScrW()*0.2 )
	cd:SetPos( ScrW() - cd:GetWide(), 0 )
	local pl = self
	function cd:OnRemove()
		pl.CountDown = nil
	end
	self.CountDown = cd
end

function PLUG:DestroyCountdown()
	if (self.CountDown) then
		self.CountDown:Remove()
		self.CountDown = nil
	end
end

function PLUG:PromptYesNo( question, callback_yes, callback_no )
	local window = vgui.Create( "DFrame" )
	window:SetTitle( "GManage" )
	window:SetDraggable( false )
	window:ShowCloseButton( false )
	local panela = vgui.Create( "DPanel", window )
	local lbl = vgui.Create( "DLabel", panela )
	lbl:SetText( question )
	lbl:SizeToContents()
	local panelb = vgui.Create( "DPanel", window )
	local btna = vgui.Create( "DImageButton", panelb )
	btna:SetMaterial( "gmanage/ico_accept" )
	function btna:DoClick()
		window:Remove()
		if (callback_yes) then callback_yes() end
	end
	local btnb = vgui.Create( "DImageButton", panelb )
	btnb:SetMaterial( "gmanage/ico_deny" )
	function btnb:DoClick()
		window:Remove()
		if (callback_no) then callback_no() end
	end
	local pad = 4
	local btnsize = 64
	local function PerformLayout()
		btna:SetSize( btnsize, btnsize )
		btnb:SetSize( btnsize, btnsize )
		panelb:SetTall( btnsize + (pad*2) )
		local lw, lh = lbl:GetWide() + 10, lbl:GetTall()
		lw = math.Clamp( lw+(pad*2), (btnsize*2) + pad, ScrW()*0.5 )
		panela:SetPos( 5, 30 )
		panela:SetSize( lw, lh+(pad*2) )
		lbl:SetPos( 5, 2 )
		panelb:SetWide( lw )
		panelb:SetPos( 5, 30 + panela:GetTall() + pad )
		local overwide = lw - ((btnsize*2) + pad)
		if (overwide < 0) then overwide = 0 end
		btna:SetPos( pad + (overwide*0.5), pad )
		btnb:SetPos( btnsize + (pad*2) + (overwide*0.5), pad )
		window:SetSize( panela:GetWide() + (pad*2), 30 + panela:GetTall() + panelb:GetTall() + (pad*2) )
		window:Center()
	end
	PerformLayout()
	function window:Paint()
		local w, h = self:GetWide(), self:GetTall()
		surface.SetDrawColor( color_black )
		surface.DrawRect( 0, 0, w, h )
		surface.SetDrawColor( color_white )
		surface.DrawOutlinedRect( 0, 0, w, h )
		surface.DrawLine( 0, 25, w, 25 )
	end
	window:MakePopup()
	window:DoModal()
end

function PLUG:CreatePrivilegeChecklist( p, x, y, w, h, used )
	local plist = vgui.Create( "DPanelList", p )
	plist:SetPos( x, y )
	plist:SetSize( w, h )
	plist:EnableHorizontal( false )
	plist:EnableVerticalScrollbar( true )
	plist:SetSpacing( 0 )
	plist:SetPadding( 2 )
	plist.Changed = {}
	local dict = plugs.MergeCallOverride( "GetPrivDictionary" )
	// PrintTable( used )
	for name, desc in SortedPairs( dict ) do
		local pn = vgui.Create( "DPanel" )
		function pn:Paint()
			if (self.Hovered || (self.CHECKBOX && self.CHECKBOX.Hovered)) then
				surface.SetDrawColor( 0, 0, 0, 100 )
				surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
			end
		end
		local lbl = vgui.Create( "DLabel", pn )
		lbl:SetText( desc )
		lbl:SizeToContents()
		local cb = vgui.Create( "DCheckBox", pn )
		cb:SetValue( table.HasValue( used, name ) )
		// print( name, c )
		function cb:OnChange()
			// print( "changed", name, self:GetChecked() )
			plist.Changed[ name ] = self:GetChecked()
			// PrintTable( plist.Changed )
		end
		pn.LABEL = lbl
		pn.CHECKBOX = cb
		function pn:PerformLayout()
			self.LABEL:SetPos( 0, 0 )
			self.CHECKBOX:SetPos( self:GetWide()-self.CHECKBOX:GetWide(), 0 )
			self:SetTall( math.Max( self.LABEL:GetTall(), self.CHECKBOX:GetTall() ) )
		end
		plist:AddItem( pn )
	end
	return plist
end

function PLUG:CreateSENTChecklist( p, x, y, w, h, used )
	local plist = vgui.Create( "DPanelList", p )
	plist:SetPos( x, y )
	plist:SetSize( w, h )
	plist:EnableHorizontal( false )
	plist:EnableVerticalScrollbar( true )
	plist:SetSpacing( 0 )
	plist:SetPadding( 2 )
	plist.Changed = {}
	local sents = plugs.MergeCallOverride( "GetStoolSentSweps" )
	// PrintTable( used )
	for _, tab in SortedPairs( sents ) do
		local pn = vgui.Create( "DPanel" )
		function pn:Paint()
			if (self.Hovered || (self.CHECKBOX && self.CHECKBOX.Hovered)) then
				surface.SetDrawColor( 0, 0, 0, 100 )
				surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
			end
		end
		local lbl = vgui.Create( "DLabel", pn )
		lbl:SetText( tab[3] )
		lbl:SizeToContents()
		local cb = vgui.Create( "DCheckBox", pn )
		cb:SetValue( !table.HasValue( used, tab[2] ) )
		// print( name, c )
		function cb:OnChange()
			// print( "changed", name, self:GetChecked() )
			plist.Changed[ tab[2] ] = self:GetChecked()
			// PrintTable( plist.Changed )
		end
		pn.LABEL = lbl
		pn.CHECKBOX = cb
		function pn:PerformLayout()
			self.LABEL:SetPos( 0, 0 )
			self.CHECKBOX:SetPos( self:GetWide()-self.CHECKBOX:GetWide(), 0 )
			self:SetTall( math.Max( self.LABEL:GetTall(), self.CHECKBOX:GetTall() ) )
		end
		plist:AddItem( pn )
	end
	return plist
end

local bgcol2 = Color( 50, 50, 50 )
function PLUG:AddPropertySheetTab( sheet, name, icon )
	local pn = vgui.Create( "DPanel" )
	function pn:Paint()
		draw.RoundedBox( 4, 0, 0, self:GetWide(), self:GetTall(), bgcol2 )
	end
	pn:SetPos( 5, 5 )
	pn:SetSize( sheet:GetWide() - 10, sheet:GetTall() - 35 )
	sheet:AddSheet( name, pn, icon, false, false, name )
	sheet:PerformLayout()
	return pn
end

local struct = {
	{ "sandbox", "Sandbox" }
}


local SandboxVars = {
	{	text = "#SBoxMaxProps",		var = "props"		},
	{	text = "#SBoxMaxRagdolls",	var = "ragdolls"	},
	{	text = "#SBoxMaxVehicles",	var = "vehicles"	},
	{	text = "#SBoxMaxEffects",	var = "effects"		},
	{	text = "#SBoxMaxBalloons",	var = "balloons"	},
	{	text = "#SBoxMaxNPCs",		var = "npcs"		},
	{	text = "#SBoxMaxSENTs",		var = "sents"		},
	{	text = "#SBoxMaxDynamite",	var = "dynamite"	},
	{	text = "#SBoxMaxLamps",		var = "lamps"		},
	{	text = "#SBoxMaxWheels",	var = "wheels"		},
	{	text = "#SBoxMaxThrusters",	var = "thrusters"	},
	{	text = "#SBoxMaxHoverBalls",	var = "hoverballs"	},
	{	text = "#SBoxMaxButtons",	var = "buttons"		},
	{	text = "#SBoxMaxEmitters",	var = "emitters"	},
	{	text = "#SBoxMaxSpawners",	var = "spawners"	},
	{	text = "#SBoxMaxTurrets",	var = "turrets"		},
} -- Courtesy of ASSMod

function PLUG:GetLimitStructure()
	return struct
end

function PLUG:GetLimits( id )
	if (id == "sandbox") then
		return SandboxVars
	end
end